package com.example.springbatch_itemreader_datasource_page;

import lombok.extern.slf4j.Slf4j;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecutionListener;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.launch.support.RunIdIncrementer;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.database.JdbcCursorItemReader;
import org.springframework.batch.item.database.JdbcPagingItemReader;
import org.springframework.batch.item.database.PagingQueryProvider;
import org.springframework.batch.item.database.builder.JdbcCursorItemReaderBuilder;
import org.springframework.batch.item.database.builder.JdbcPagingItemReaderBuilder;
import org.springframework.batch.item.database.support.SqlPagingQueryProviderFactoryBean;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.jdbc.core.ArgumentPreparedStatementSetter;

import javax.annotation.Resource;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@SpringBootApplication
@EnableBatchProcessing
@Slf4j
public class SpringApplication17 {

    public static void main(String[] args) {
        SpringApplication.run(SpringApplication17.class, args);
    }

    @Resource
    private JobBuilderFactory jobBuilderFactory;

    @Resource
    private StepBuilderFactory stepBuilderFactory;


    @Resource(name = "myJobExecutionListener")
    private JobExecutionListener jobExecutionListener;

    @Resource
    private DataSource dataSource;

    @Resource(name = "userRowMapper")
    private UserRowMapper userRowMapper;

    @Bean
    public ItemWriter<User> itemWriter() {
        return new ItemWriter<User>() {
            @Override
            public void write(List<? extends User> list) throws Exception {
                list.forEach(System.out::println);
            }
        };
    }

// @Bean
// public JdbcCursorItemReader<User> jdbcCursorItemReader(){
//
//
//     return new JdbcCursorItemReaderBuilder<User>()
//             .name("jdbcCursorBuilder")
//             // 定义数据源
//             .dataSource(dataSource)
//             // 定义执行的sql
//             .sql("select * from user where age > ?")
//             // 映射的方式
//             .rowMapper(userRowMapper)
//             // 拼接参数
//             .preparedStatementSetter(new ArgumentPreparedStatementSetter(new Object[]{16}))
//             .build();
//
// }

    /**
     * 分页查询对象
     *
     * @return
     */
    @Bean
    public PagingQueryProvider pagingQueryProvider() {

        SqlPagingQueryProviderFactoryBean providerFactoryBean = new SqlPagingQueryProviderFactoryBean();
        providerFactoryBean.setDataSource(dataSource);
        providerFactoryBean.setSelectClause("select *");   // 设置查询列
        providerFactoryBean.setFromClause("from user");  // 设置查询表
        providerFactoryBean.setWhereClause("where age > :age");  //设置查询条件
        providerFactoryBean.setSortKey("id");

        try {
            // 返回查询对象
            return providerFactoryBean.getObject();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }

    /**
     * 自定义分页读取
     *
     * @return
     */
    @Bean
    public JdbcPagingItemReader<User> jdbcPagingItemReader() {
        Map<String, Object> params = new HashMap<>();
        params.put("age", 15);

        return new JdbcPagingItemReaderBuilder<User>()
                .name("jdbcItemReaderBuilder")
                .dataSource(dataSource)  // 数据源
                .rowMapper(userRowMapper) //映射方式
                .pageSize(10)  //分页参数
                .parameterValues(params)  // 参数
                .queryProvider(pagingQueryProvider())  // 设置分页查询对象
                .build();
    }


    @Bean
    public Step step() {
        return stepBuilderFactory
                .get("step")
                .<User, User>chunk(1)
//                .reader(userItemReader())
                .reader(jdbcPagingItemReader())
                .writer(itemWriter())
                .build();
    }

    @Bean
    public Job job() {
        return jobBuilderFactory.get("sql-faster-json-page").start(step()).
                incrementer(new RunIdIncrementer())
                .listener(jobExecutionListener)
                .build();
    }


}
